#ifndef READERWRITER_H
#define READERWRITER_H

class ReaderWriter {
public:
	ReaderWriter(int sockfd);
	int read(char * data, int len);
	int write(const char * data, int len);
	      
	void setUseCompression(bool useCompression){ this->useCompression = useCompression; }

	std::string compress( const std::string& data );
	std::string decompress( const std::string& data );

private:
	int sockfd;
	bool useCompression;
    z_stream * m_zinflate;
    z_stream * m_zdeflate;
}

class Reader
{
public:
    Reader() : sock(-1){};
    Reader(int sock) : sock(sock){};
	void setSockfd(int sockfd) {sock = sockfd;}
	void init(int sockfd, bool useCompression) {sock = sockfd; this->useCompression = useCompression; }
    int read(char * s, int size) {
		return ::recv( sock, s, size, 0 );
    };
    const Reader& operator=(const Reader& rhs) {
	sock = rhs.sock;
    };

	void setUseCompression(bool useCompression){ this->useCompression = useCompression; }
	std::string decompress( const std::string& data );
private:
    int sock;
	bool useCompression;
    z_stream * m_zinflate;
    z_stream * m_zdeflate;
};

class Writer
{
public:
    Writer() : sock(-1){};
    Writer(int sock) : sock(sock){};
	void setSockfd(int sockfd) {sock = sockfd;}
	void init(int sockfd, bool useCompression) {sock = sockfd; this->useCompression = useCompression; }
    int write(const char * s, int size){
		return ::send( sock, s, size, 0 );
    };
	const Writer& operator=(const Writer& rhs) {
	sock = rhs.sock;
    };

	void setUseCompression(bool useCompression){ this->useCompression = useCompression; }
	std::string compress( const std::string& data );

private:
	int sock;
	bool useCompression;
    z_stream * m_zinflate;
    z_stream * m_zdeflate;
};

#endif //READERWRITER_H
